package com.ruoyi.oa.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.oa.domain.OaProject;
import com.ruoyi.oa.domain.OaPurchaseApply;
import com.ruoyi.oa.domain.OaPurchaseApplyList;
import com.ruoyi.oa.domain.bo.OaPurchaseApplyBo;
import com.ruoyi.oa.domain.bo.OaPurchaseApplyListBo;
import com.ruoyi.oa.domain.vo.OaPurchaseApplyListVo;
import com.ruoyi.oa.domain.vo.OaPurchaseApplyVo;
import com.ruoyi.oa.mapper.OaPurchaseApplyListMapper;
import com.ruoyi.oa.mapper.OaPurchaseApplyMapper;
import com.ruoyi.oa.service.IOaPurchaseApplyService;
import com.ruoyi.workflow.service.IProcessInstanceService;
import com.ruoyi.workflow.service.IUserService;
import com.ruoyi.workflow.utils.WorkFlowUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 采购申请Service业务层处理
 *
 * @author ruoyi
 * @date 2023-03-28
 */
@RequiredArgsConstructor
@Service
public class OaPurchaseApplyServiceImpl implements IOaPurchaseApplyService {

    private final OaPurchaseApplyMapper baseMapper;

    private final OaPurchaseApplyListMapper oaPurchaseApplyListMapper;

    private final IProcessInstanceService iProcessInstanceService;

    private final IUserService iUserService;

    private final OaProjectServiceImpl oaProjectService;
    /**
     * 查询采购申请
     */
    @Override
    public OaPurchaseApplyVo queryById(String id){
        OaPurchaseApplyVo applyVo = baseMapper.selectVoById(id);
        WorkFlowUtils.setStatusFileValue(applyVo,applyVo.getId());
        OaPurchaseApplyListBo bo=new OaPurchaseApplyListBo();
        bo.setGqdId(id);
        List<OaPurchaseApplyListVo> list = queryOaPurchaseApplyList(bo);
        applyVo.setPurchaseApplyListVoList(list);
        return applyVo;
    }

    /**
     * 通过项目名称查询采购申请
     * @param projectName
     * @return
     */
    @Override
    public OaPurchaseApplyVo queryByProjectName(String projectName) {
        LambdaQueryWrapper<OaPurchaseApply> lqw = Wrappers.lambdaQuery();
        lqw.eq(OaPurchaseApply::getProjectName, projectName);
        OaPurchaseApplyVo vo = baseMapper.selectVoOne(lqw);
        if (ObjectUtil.isEmpty(vo)){
            return null;
        }
        WorkFlowUtils.setStatusFileValue(vo,vo.getId());
        OaPurchaseApplyListBo bo=new OaPurchaseApplyListBo();
        bo.setGqdId(vo.getId());
        List<OaPurchaseApplyListVo> list = queryOaPurchaseApplyList(bo);
        vo.setPurchaseApplyListVoList(list);
        return vo;
    }

    /**
     * 查询采购申请列表
     */
    @Override
    public TableDataInfo<OaPurchaseApplyVo> queryPageList(OaPurchaseApplyBo bo, PageQuery pageQuery) {
        if (StringUtils.isNotBlank(bo.getCreateBy())){
            String userName = iUserService.getUserNameByNickName(bo.getCreateBy());
            if (StringUtils.isNotBlank(userName)){
                bo.setCreateBy(userName);
            }
        }
        if (CollectionUtil.isNotEmpty(bo.getSubmitTimeList())){
            bo.setSubmitStartDate(bo.getSubmitTimeList().get(0));
            bo.setSubmitEndDate(bo.getSubmitTimeList().get(1));
        }
        List<OaPurchaseApplyVo> voList = baseMapper.queryByCondition(bo);
        // 添加流程信息
        if (CollectionUtil.isNotEmpty(voList)) {
            List<String> list = voList.stream().map(OaPurchaseApplyVo::getId).collect(Collectors.toList());
            WorkFlowUtils.setStatusListFileValue(voList, list, "id");
        }
        // 筛选状态
        if (StringUtils.isNotBlank(bo.getStatus())) {
            List<OaPurchaseApplyVo> temp = new ArrayList<>();
            for (OaPurchaseApplyVo vo : voList) {
                if (vo.getActBusinessStatus().getStatus().equals(bo.getStatus())) {
                    temp.add(vo);
                }
            }
            voList = temp;
        }

        // 筛选提交时间
        if (CollectionUtil.isNotEmpty(bo.getSubmitTimeList())) {
            List<OaPurchaseApplyVo> temp = new ArrayList<>();
            Date submitStartDate = bo.getSubmitStartDate();
            Date submitEndDate = bo.getSubmitEndDate();
            for (OaPurchaseApplyVo vo : voList) {
                Date createTime = vo.getActBusinessStatus().getCreateTime();
                if (ObjectUtil.isNotEmpty(createTime) && createTime.after(submitStartDate) && createTime.before(submitEndDate)) {
                    temp.add(vo);
                }
            }
            voList = temp;
        }

        // 筛选提交人
        if (StringUtils.isNotEmpty(bo.getCreateBy())) {
            String[] split = bo.getCreateBy().split(",");
            List<String> list = Arrays.asList(split);
            List<OaPurchaseApplyVo> temp = new ArrayList<>();
            for (OaPurchaseApplyVo vo : voList) {
                if (ObjectUtil.isNotEmpty(vo.getActBusinessStatus().getCreateTime()) && list.indexOf(vo.getActBusinessStatus().getCreateBy())!=-1) {
                    temp.add(vo);
                }
            }
            voList = temp;
        }

        Page<OaPurchaseApplyVo> result = new Page<>();
        result.setTotal(voList.size());

        int start = (pageQuery.getPageNum() - 1) * pageQuery.getPageSize();
        int end = Math.min(pageQuery.getPageNum() * pageQuery.getPageSize(), voList.size());
        voList = voList.subList(start, end);

        result.setRecords(voList);
        result.setCurrent(pageQuery.getPageNum());
        result.setSize(pageQuery.getPageSize());

        return TableDataInfo.build(result);
    }

    /**
     * 查询子表
     * @param bo
     * @return
     */
    public List<OaPurchaseApplyListVo> queryOaPurchaseApplyList(OaPurchaseApplyListBo bo) {
        LambdaQueryWrapper<OaPurchaseApplyList> lqw = buildQueryListWrapper(bo);
        return oaPurchaseApplyListMapper.selectVoList(lqw);
    }

    /**
     * 查询采购申请列表
     */
    @Override
    public List<OaPurchaseApplyVo> queryList(OaPurchaseApplyBo bo) {
        LambdaQueryWrapper<OaPurchaseApply> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 构造采购申请查询条件
     * @param bo
     * @return
     */
    private LambdaQueryWrapper<OaPurchaseApply> buildQueryWrapper(OaPurchaseApplyBo bo) {
//        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<OaPurchaseApply> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), OaPurchaseApply::getCreateBy,bo.getCreateBy());
        lqw.orderByDesc(OaPurchaseApply::getCreateTime);
        if (CollectionUtil.isNotEmpty(bo.getSubmitTimeList())) {
            lqw.gt(OaPurchaseApply::getCreateTime, bo.getSubmitTimeList().get(0));
            lqw.lt(OaPurchaseApply::getCreateTime, bo.getSubmitTimeList().get(1));
        }
        lqw.like(StringUtils.isNotBlank(bo.getCreateBy()), OaPurchaseApply::getCreateBy, bo.getCreateBy());
        lqw.like(StringUtils.isNotBlank(bo.getProjectName()), OaPurchaseApply::getProjectName, bo.getProjectName());
        lqw.eq(StringUtils.isNotBlank(bo.getProjectAddress()), OaPurchaseApply::getProjectAddress, bo.getProjectAddress());
        lqw.like(bo.getTotal()!=0, OaPurchaseApply::getTotal, bo.getTotal());
        lqw.gt(StringUtils.isNotBlank(bo.getPurchaseMoneyStart()),OaPurchaseApply::getTotal,bo.getPurchaseMoneyStart());
        lqw.lt(StringUtils.isNotBlank(bo.getPurchaseMoneyEnd()),OaPurchaseApply::getTotal,bo.getPurchaseMoneyEnd());
        lqw.like(StringUtils.isNotBlank(bo.getCapitalization()), OaPurchaseApply::getCapitalization, bo.getCapitalization());
        return lqw;
    }

    /**
     * 构造子表查询wrapper
     * @param bo
     * @return
     */
    private LambdaQueryWrapper<OaPurchaseApplyList> buildQueryListWrapper(OaPurchaseApplyListBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<OaPurchaseApplyList> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getGqdId()), OaPurchaseApplyList::getGqdId, bo.getGqdId());
        lqw.like(StringUtils.isNotBlank(bo.getItemName()), OaPurchaseApplyList::getItemName, bo.getItemName());
        lqw.eq(StringUtils.isNotBlank(bo.getSpecificationModel()), OaPurchaseApplyList::getSpecificationModel, bo.getSpecificationModel());
        lqw.eq(StringUtils.isNotBlank(bo.getNumber()), OaPurchaseApplyList::getNumber, bo.getNumber());
        lqw.eq(StringUtils.isNotBlank(bo.getUnity()), OaPurchaseApplyList::getUnity, bo.getUnity());
        lqw.eq(StringUtils.isNotBlank(bo.getUnitPrice()), OaPurchaseApplyList::getUnitPrice, bo.getUnitPrice());
        lqw.eq(StringUtils.isNotBlank(bo.getTotalPrice()), OaPurchaseApplyList::getTotalPrice, bo.getTotalPrice());
        lqw.eq(bo.getDemandDate() != null, OaPurchaseApplyList::getDemandDate, bo.getDemandDate());
        lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), OaPurchaseApplyList::getRemarks, bo.getRemarks());
        return lqw;
    }

    /**
     * 新增采购申请
     */
    @Override
    public OaPurchaseApplyBo insertByBo(OaPurchaseApplyBo bo) {
        LoginUser currentUser = LoginHelper.getLoginUser();
        bo.setDeptId(currentUser.getDeptId());
        bo.setUserId(currentUser.getUserId());
        OaPurchaseApply add = BeanUtil.toBean(bo, OaPurchaseApply.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        List<OaPurchaseApplyListBo> bos = bo.getPurchaseApplyListBoList();
        if (CollectionUtil.isNotEmpty(bos)){
            List<Integer> collect = bos.stream().map(d -> {
                OaPurchaseApplyList list = BeanUtil.toBean(d, OaPurchaseApplyList.class);
                list.setGqdId(bo.getId());
                int insert = oaPurchaseApplyListMapper.insert(list);
                return insert;
            }).collect(Collectors.toList());
        }
        return bo;
    }

    /**
     * 修改采购申请
     */
    @Override
    public OaPurchaseApply updateByBo(OaPurchaseApplyBo bo) {
        OaPurchaseApply update = BeanUtil.toBean(bo, OaPurchaseApply.class);
        validEntityBeforeSave(update);
        baseMapper.updateById(update);
        List<OaPurchaseApplyListBo> bos = bo.getPurchaseApplyListBoList();
        if (CollectionUtil.isNotEmpty(bos)){
            List<Boolean> collect = bos.stream().map(d -> {
                OaPurchaseApplyList oaPurchaseApplyList = BeanUtil.toBean(d, OaPurchaseApplyList.class);
                oaPurchaseApplyList.setGqdId(bo.getId());
                boolean b = oaPurchaseApplyListMapper.insertOrUpdate(oaPurchaseApplyList);
                return b;
            }).collect(Collectors.toList());
        }
        return update;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(OaPurchaseApply entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除采购申请
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        for (String id : ids) {
            String processInstanceId = iProcessInstanceService.getProcessInstanceId(id);
            if(StringUtils.isNotBlank(processInstanceId)){
                iProcessInstanceService.deleteRuntimeProcessAndHisInst(processInstanceId);
            }
        }
        ids.stream().map(d -> {
            OaPurchaseApplyListBo listBo = new OaPurchaseApplyListBo();
            listBo.setGqdId(d);
            List<OaPurchaseApplyListVo> applyList = queryOaPurchaseApplyList(listBo);
            List<Integer> collect = applyList.stream().map(dm -> {
                OaPurchaseApplyList list = BeanUtil.toBean(dm, OaPurchaseApplyList.class);
                int delete = oaPurchaseApplyListMapper.deleteById(list);
                return delete;
            }).collect(Collectors.toList());
            return d;
        }).collect(Collectors.toList());
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<OaProject> getProjectList(){
        List<OaProject> list = oaProjectService.getProjectName();
        List<OaPurchaseApply> applyList = baseMapper.selectList();
        List<String> collect = applyList.stream().map(OaPurchaseApply::getProjectName).collect(Collectors.toList());
        list=list.stream().filter(d->{
            if (collect.indexOf(d.getProjectName())==-1){
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        return list;
    }
}
